package com.zky.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zky.domain.ResponseResult;
import com.zky.domain.dto.RoleDto;
import com.zky.domain.entity.Role;
import com.zky.domain.entity.RoleMenu;
import com.zky.domain.vo.PageVo;
import com.zky.domain.vo.RoleVo;
import com.zky.enums.AppHttpCodeEnum;
import com.zky.mapper.RoleMapper;
import com.zky.service.RoleMenuService;
import com.zky.service.RoleService;
import com.zky.utils.BeanCopyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 角色信息表(Role)表服务实现类
 *
 * @author makejava
 * @since 2023-08-07 14:20:45
 */
@Service("roleService")
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Autowired
    private RoleService roleService;

    @Autowired
    private RoleMenuService roleMenuService;

    @Autowired(required = false)
    private RoleMapper roleMapper;

    @Override
    public List<String> selectRoleKeyByUserId(Long id) {
        //判断是否是管理员 如果是返回集合中只需要有admin
        if(id == 1L){
            List<String> roleKeys = new ArrayList<>();
            roleKeys.add("admin");
            return roleKeys;
        }
        //否则查询用户所具有的角色信息
        return getBaseMapper().selectRoleKeyByUserId(id);
    }

    @Override
    public ResponseResult getAllRoleByPage(Integer pageNum, Integer pageSize, String roleName, String status) {
        //针对角色名称进行模糊查询
        LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.hasText(roleName),Role::getRoleName,roleName);
        //针对状态进行查询
        wrapper.eq(StringUtils.hasText(status),Role::getStatus,status);
        //按照role_sort进行升序排列
        wrapper.orderByAsc(Role::getRoleSort);
        //分页查询
        Page<Role> page = new Page<>(pageNum, pageSize);
        page(page,wrapper);
        //封装返回结果
        List<RoleVo> roleVos = BeanCopyUtils.copyBeanList(page.getRecords(), RoleVo.class);
        PageVo pageVo = new PageVo(roleVos, page.getTotal());
        return ResponseResult.okResult(pageVo);
    }

    @Override
    public ResponseResult changeRoleStatus(Integer roleId, Integer status) {
        LambdaUpdateWrapper<Role> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(Role::getId,roleId);
        wrapper.set(Role::getStatus,status);
        roleService.update(wrapper);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult addRole(RoleDto roleDto) {
        //根据角色名判断当前角色是否存在
        if (!this.judgeRole(roleDto.getRoleName())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR,"该角色名已存在");
        }
        //根据权限名判断当前角色是否存在
        if (!this.judgeRoleKey(roleDto.getRoleKey())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR,"该权限名已存在");
        }

        //获取到当前角色的菜单权限列表
        List<Long> menuIds = roleDto.getMenuIds();
        //将RoleDto对象转换为Role对象
        save(BeanCopyUtils.copyBean(roleDto, Role.class));

        //根据角色名获取到当前角色
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Role::getRoleName, roleDto.getRoleName());
        Role role = getOne(queryWrapper);   //从数据库里重新获取刚刚存入的对象，才能拿到它的id
        //遍历menuIds，添加到sys_role_menu表中
        for (Long menuId : menuIds) {
            roleMenuService.save(new RoleMenu(role.getId(), menuId));
        }
        return ResponseResult.okResult();
    }

    /**
     * 判断角色是否存在
     *
     * @param roleName
     * @return
     */
    public boolean judgeRole(String roleName) {
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(Role::getRoleName, roleName);
        Role role = roleService.getOne(queryWrapper);
        if (Objects.isNull(role)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 判断权限是否存在
     *
     * @param roleKey
     * @return
     */
    public boolean judgeRoleKey(String roleKey) {
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(Role::getRoleKey, roleKey);
        Role role = roleService.getOne(queryWrapper);
        if (Objects.isNull(role)) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public ResponseResult getRoleInfoById(Long id) {
        Role role = roleService.getById(id);
        RoleVo roleVo = BeanCopyUtils.copyBean(role, RoleVo.class);
        return ResponseResult.okResult(roleVo);
    }

    @Override
    public ResponseResult updateRoleInfo(RoleDto roleDto) {
        // 判断LinkDto对象值是否为空
        if (!StringUtils.hasText(roleDto.getRoleName()) ||
                !StringUtils.hasText(roleDto.getRoleKey()) ||
                !StringUtils.hasText(String.valueOf(roleDto.getStatus())) ||
                !StringUtils.hasText(String.valueOf(roleDto.getRoleSort()))) {
            return ResponseResult.errorResult(AppHttpCodeEnum.CONTENT_IS_BLANK);
        }

        // 获取到当前角色的菜单权限列表
        List<Long> menuIds = roleDto.getMenuIds();

        // 将RoleDto对象转换为Role对象
        Role role = BeanCopyUtils.copyBean(roleDto, Role.class);
        updateById(role);

        // 根据roleId移除sys_role_menu表中的数据
        LambdaQueryWrapper<RoleMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RoleMenu::getRoleId, role.getId());
        roleMenuService.remove(queryWrapper);
        // 遍历修改后的用户的menuIds列表，添加到sys_role_menu表中
        for (Long menuId : menuIds) {
            roleMenuService.save(new RoleMenu(role.getId(), menuId));
        }
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult deleteRole(Long id) {
        LambdaQueryWrapper<RoleMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RoleMenu::getRoleId, id);
        roleMenuService.remove(queryWrapper);
        removeById(id);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult getListAllRole() {
        List<Role> roles = roleMapper.selectList(null);
        return ResponseResult.okResult(roles);
    }
}

